package com.ej.busi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ej.busi.domain.*;
import com.ej.busi.dto.course.EjUserCourseDetailDto;
import com.ej.busi.dto.course.EjUserCourseStatisticsDto;
import com.ej.busi.dto.course.EjUserCourseDto;
import com.ej.busi.mapper.EjUserCourseMapper;
import com.ej.busi.service.*;
import com.ej.common.dto.BasePieChartDataAndItemDto;
import com.ej.common.dto.BasePieChartDataDto;
import com.ej.common.exception.base.BaseException;
import com.ej.common.utils.SecurityUtils;
import com.ej.common.utils.StringUtils;
import com.ej.common.utils.bean.BeanUtils;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 课程表 服务层实现
 * 
 * @author ej
 */
@Service
public class EjUserCourseServiceImpl extends ServiceImpl<EjUserCourseMapper, EjUserCourse> implements IEjUserCourseService {

    @Autowired
    private IEjCourseService courseService;

    @Autowired
    private IEjUserWordService userWordService;

    @Autowired
    private IEjPeriodWordService periodWordService;

    @Override
    public List<EjUserCourseDto> userCourseList(Long subjectId, String courseName) {

        List<EjUserCourseDto> result = Lists.newArrayList();

        /**
         * 获取用户id
         */
        Long userId = SecurityUtils.getLoginUser().getUserId();
        if (userId == null){
            throw new BaseException("请先登录!");
        }

        // 用户和课程关联表
        List<EjUserCourse> allUserCourses = this.list(Wrappers.<EjUserCourse>lambdaQuery().eq(EjUserCourse::getUserId, userId));
        Map<Long, List<EjUserCourse>> allUserCoursesMap = allUserCourses.stream().collect(Collectors.groupingBy(EjUserCourse::getCourseId));

        LambdaQueryWrapper<EjCourse> courseQuery = Wrappers.<EjCourse>lambdaQuery().in(EjCourse::getId, allUserCourses.stream().map(EjUserCourse::getCourseId).distinct().collect(Collectors.toList()));
        if (StringUtils.isNotEmpty(courseName)){
            courseQuery.like(EjCourse :: getName, courseName);
        }

        if (subjectId != null){
            courseQuery.eq(EjCourse :: getSubjectId, subjectId);
        }

        // 获取课程详细信息
        List<EjCourse> courseList = courseService.list(courseQuery);
        if (CollectionUtils.isEmpty(courseList)){
            return result;
        }
        Map<Long, EjCourse> courseMap = courseList.stream().collect(Collectors.toMap(entity -> entity.getId(), Function.identity()));

        allUserCoursesMap.keySet().forEach( key -> {
            EjUserCourseDto ejUserCourseDto = new EjUserCourseDto();
            List<EjUserCourse> userCourses = allUserCoursesMap.get(key);
            EjUserCourse ejUserCourse = userCourses.stream().sorted(Comparator.comparing(EjUserCourse::getEffectiveTime)).collect(Collectors.toList()).get(0);
            BeanUtils.copyBeanProp(ejUserCourseDto, courseMap.get(key));
            ejUserCourseDto.setCourseStatus(ejUserCourse.getEffectiveTime().after(new Date()) ? "0" : "1");
            result.add(ejUserCourseDto);
        });

        return result;
    }

    @Override
    public EjUserCourseStatisticsDto userCourseStatistics(Long courseId) {

        EjUserCourseStatisticsDto result  = new EjUserCourseStatisticsDto();

        /**
         * 获取用户id
         */
        Long userId = SecurityUtils.getLoginUser().getUserId();
        if (userId == null){
            throw new BaseException("请先登录!");
        }
        // 判断用户是否购买课程
        List<EjUserCourse> userCourseList = this.list(Wrappers.<EjUserCourse>lambdaQuery().eq(EjUserCourse::getCourseId, courseId).eq(EjUserCourse::getUserId, userId));
        if (CollectionUtils.isEmpty(userCourseList)){
            throw new BaseException("请先购买该课程!");
        }

        // 获取课程
        EjCourse course = courseService.getById(courseId);
        result.setCourseName(course.getName());

        // 获取所有章节
        List<EjPeriodWord> periodWordList = periodWordService.list(Wrappers.<EjPeriodWord>lambdaQuery().eq(EjPeriodWord::getCourseId, courseId));
        Map<String, List<EjPeriodWord>> periodWordListMap = periodWordList.stream().collect(Collectors.groupingBy(m -> m.getChapterId() + "-" + m.getPeriodId()));

        // 获取总课时
        int coursePeriodTotal = periodWordListMap.keySet().size();
        result.setCoursePeriodTotal(Long.valueOf(coursePeriodTotal));

        // 获取汇量表
        int courseWordTotal = periodWordList.size();
        result.setCourseWordTotal(Long.valueOf(courseWordTotal));

        // 获取用户该课程已学词汇量表
        List<EjUserWord> userCourseWordList = userWordService.list(Wrappers.<EjUserWord>lambdaQuery().eq(EjUserWord::getCourseId, courseId).eq(EjUserWord::getUserId, userId));
        int courseUserWordTotal = userCourseWordList.size();
        result.setCourseUserWordTotal(Long.valueOf(courseUserWordTotal));
        int courseUserPeriodTotal = 0;
        if(CollectionUtils.isNotEmpty(userCourseWordList)){
            // 获取用于已学课时
            List<EjPeriodWord> userPeriodWordList = periodWordService.list(Wrappers.<EjPeriodWord>lambdaQuery().in(EjPeriodWord::getId, userCourseWordList.stream().map(s -> s.getPeriodWordId()).collect(Collectors.toList())));
            Map<String, List<EjPeriodWord>> userPeriodWordListMap = userPeriodWordList.stream().collect(Collectors.groupingBy(m -> m.getChapterId() + "-" + m.getPeriodId()));
            courseUserPeriodTotal = userPeriodWordListMap.keySet().size();
        }

        result.setCourseUserPeriodTotal(Long.valueOf(courseUserPeriodTotal));

        return result;
    }

    @Override
    public List<BasePieChartDataDto> userCourseChapter(Long courseId) {

        List<BasePieChartDataDto> result = Lists.newArrayList();
        /**
         * 获取用户id
         */
        Long userId = SecurityUtils.getLoginUser().getUserId();
        if (userId == null){
            throw new BaseException("请先登录!");
        }
        // 判断用户是否购买课程
        List<EjUserCourse> userCourseList = this.list(Wrappers.<EjUserCourse>lambdaQuery().eq(EjUserCourse::getCourseId, courseId).eq(EjUserCourse::getUserId, userId));
        if (CollectionUtils.isEmpty(userCourseList)){
            throw new BaseException("请先购买该课程!");
        }
        // 获取所有章节
        List<EjPeriodWord> periodWordList = periodWordService.list(Wrappers.<EjPeriodWord>lambdaQuery().eq(EjPeriodWord::getCourseId, courseId));
        Map<Integer, List<EjPeriodWord>> periodWordListMap = periodWordList.stream().collect(Collectors.groupingBy(m -> m.getChapterId()));
        periodWordListMap.keySet().forEach( key -> {
            BasePieChartDataDto dto = new BasePieChartDataAndItemDto();
            dto.setId(key.toString());
            dto.setText("Unit" + key);
            result.add(dto);
        });
        return result;
    }

    @Override
    public EjUserCourseDetailDto userCourseDetail(Long courseId) {
        EjUserCourseDetailDto result = new EjUserCourseDetailDto();
        /**
         * 获取用户id
         */
        Long userId = SecurityUtils.getLoginUser().getUserId();
        if (userId == null){
            throw new BaseException("请先登录!");
        }
        // 判断用户是否购买课程
        List<EjUserCourse> userCourseList = this.list(Wrappers.<EjUserCourse>lambdaQuery().eq(EjUserCourse::getCourseId, courseId).eq(EjUserCourse::getUserId, userId));
        if (CollectionUtils.isEmpty(userCourseList)){
            throw new BaseException("请先购买该课程!");
        }

        // 获取课程
        EjCourse course = courseService.getById(courseId);
        result.setCourseName(course.getName());
        result.setCoursePic(course.getPreviewPic1());

        result.setEffectiveTime(userCourseList.get(0).getEffectiveTime());

        result.setEffectiveStatus(userCourseList.get(0).getEffectiveTime().after(new Date()) ? "0" : "1");
        return result;
    }
}
